package cn.tedu.tmall.admin.account.service.impl;

import cn.tedu.tmall.admin.account.dao.cache.IUserCacheRepository;
import cn.tedu.tmall.admin.account.dao.cache.impl.UserCacheRepository;
import cn.tedu.tmall.admin.account.dao.persist.repository.IRoleRepositoy;
import cn.tedu.tmall.admin.account.dao.persist.repository.IUserRepository;
import cn.tedu.tmall.admin.account.dao.persist.repository.IUserRoleRepository;
import cn.tedu.tmall.admin.account.pojo.entity.User;
import cn.tedu.tmall.admin.account.pojo.entity.UserRole;
import cn.tedu.tmall.admin.account.pojo.param.UserAddNewParam;
import cn.tedu.tmall.admin.account.pojo.param.UserUpdateInfoParam;
import cn.tedu.tmall.admin.account.pojo.vo.RoleStandardVO;
import cn.tedu.tmall.admin.account.pojo.vo.UserListItemVO;
import cn.tedu.tmall.admin.account.pojo.vo.UserStandardVO;
import cn.tedu.tmall.admin.account.service.IUserService;
import cn.tedu.tmall.common.enumerator.ServiceCode;
import cn.tedu.tmall.common.ex.ServiceException;
import cn.tedu.tmall.common.pojo.po.UserStatePO;
import cn.tedu.tmall.common.pojo.vo.PageData;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

@Service
@Slf4j
public class UserService implements IUserService {
    @Autowired
    private PasswordEncoder passwordEncoder;
    @Autowired
    private IUserRepository userRepository;
    @Autowired
    private IUserRoleRepository userRoleRepository;
    @Autowired
    private IRoleRepositoy roleRepositoy;
    @Autowired
    private IUserCacheRepository userCacheRepository;

    @Override
    public void addNew(UserAddNewParam userAddNewParam) {
        log.debug("开始处理用户登录的信息");
        // 判断用户名是否被占用
        {
            String username = userAddNewParam.getUsername();
            int count = userRepository.countByUsername(username);
            if (count > 0) {
                String message = "添加用户失败,用户名已经被占用";
                throw new ServiceException(ServiceCode.ERROR_CONFLICT, message);
            }
        }

        // 判断手机号是否正确
        {
            String phone = userAddNewParam.getPhone();
            int count = userRepository.countByPhone(phone);
            if (count > 0) {
                String message = "添加用户失败,手机号已经被占用";
                throw new ServiceException(ServiceCode.ERROR_CONFLICT, message);
            }
        }

        // 判断邮箱是否被占用
        {
            String email = userAddNewParam.getEmail();
            int count = userRepository.countByEmail(email);
            if (count > 0) {
                String message = "添加用户失败,电子邮箱已经被占用";
                throw new ServiceException(ServiceCode.ERROR_CONFLICT, message);
            }
        }

        User user = new User();
        BeanUtils.copyProperties(userAddNewParam, user);
        user.setLoginCount(0);
        String password = user.getPassword();
        // 做密文处理
        String encode = passwordEncoder.encode(password);
        user.setPassword(encode);
        int insert = userRepository.insert(user);
        // 判断是否添加数据成功
        if (insert != 1) {
            String message = "添加用户失败，服务器忙，请稍后再尝试! ";
            throw new ServiceException(ServiceCode.ERROR_INSERT, message);
        }

        // 插入用户角色关联数据
        Long[] roleIds = userAddNewParam.getRoleIds();
        if (roleIds == null || roleIds.length == 0) {
            return;
        }
        List<UserRole> userRoleList = new ArrayList<>();
        for (Long roled : roleIds) {
            // 检查角色是否存在
            RoleStandardVO roleStandardVO = roleRepositoy.selectById(roled);
            if (roleStandardVO == null) {
                String message = "角色添加失败";
                throw new ServiceException(ServiceCode.ERROR_NOT_FOUND, message);
            }
            // 判断添加用户角色权限是否成功
            UserRole userRole = new UserRole();
            userRole.setUserId(user.getId());
            userRole.setRoleId(roled);
            userRoleList.add(userRole);
        }
        int i = userRoleRepository.insertBatch(userRoleList);
        if (i < 1) {
            String message = "添加用户失败，服务器忙，请稍后再尝试！";
            throw new ServiceException(ServiceCode.ERROR_INSERT, message);
        }
    }

    @Override
    public void updateInfo(Long userId, UserUpdateInfoParam userUpdateInfoParam) {
        log.debug("开始处理【修改基本信息】的业务，用户ID：{}，新基本信息：{}", userId, userUpdateInfoParam);
        User user = new User();
        BeanUtils.copyProperties(userUpdateInfoParam, user);
        user.setId(userId);
        int rows = userRepository.updateById(user);
        if (rows != 1) {
            String message = "修改基本信息失败，服务器忙，请稍后再尝试！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERROR_UPDATE, message);
        }
    }

    @Override
    public void updatePassword(Long userId, String newPassword) {
        log.debug("开始处理修改用户密码");
        String encodePassword = passwordEncoder.encode(newPassword);
        User user = new User();
        user.setId(userId);
        user.setPassword(encodePassword);
        int i = userRepository.updateById(user);
        if (i != 1) {
            String message = "修改密码失败,服务器繁忙";
            throw new ServiceException(ServiceCode.ERROR_UPDATE, message);
        }
    }

    @Override
    public void updateAvatar(Long userId, String avatar) {
        log.debug("开始修改头像");
        User user = new User();
        user.setId(userId);
        user.setAvatar(avatar);
        int i = userRepository.updateById(user);
        if (i != 1) {
            String message = "修改头像失败,服务器繁忙";
            throw new ServiceException(ServiceCode.ERROR_UPDATE, message);
        }
    }

    @Override
    public void updatePhone(Long userId, String phone) {
        // 判断手机号是否重复
        int count = userRepository.countByPhoneAndNotId(phone, userId);
        if (count > 0) {
            String message = "修改手机号码失败,手机号被占用";
            throw new ServiceException(ServiceCode.ERROR_CONFLICT, message);
        }

        log.debug("开始修改手机号");
        User user = new User();
        user.setId(userId);
        user.setPhone(phone);
        int i = userRepository.updateById(user);
        // 判断手机号是否修改成功
        if (i != 1) {
            String message = "修改手机号失败,服务器繁忙";
            throw new ServiceException(ServiceCode.ERROR_UPDATE, message);
        }
    }

    @Override
    public void updateEmail(Long userId, String email) {
        // 判断手邮箱是否被占用
        int count = userRepository.countByEmailAndNotId(userId, email);
        if (count>0){
            String message="修改邮箱失败,邮箱被占用";
            throw new ServiceException(ServiceCode.ERROR_CONFLICT,message);
        }

        log.debug("开始修改邮箱");
        User user=new User();
        user.setId(userId);
        user.setEmail(email);
        int i = userRepository.updateById(user);
        if (i!=1){
            String message="修改邮箱失败,服务器繁忙";
            throw new ServiceException(ServiceCode.ERROR_CONFLICT,message);
        }
    }

    // TODO 不知道怎么写
    @Override
    public void setDisable(Long userId) {
        log.debug("开始处理禁用用户的业务");
        updateEnableById(userId,ENABLE_STATE_OFF);
    }

    @Override
    public void setEnable(Long userId) {
        log.debug("开始处理启用用户的业务");
        updateEnableById(userId,ENABLE_STATE_ON);
    }

    // TODO 不知道怎么写
    @Override
    public UserStandardVO getStandardById(Long userId) {
        log.debug("开始处理根据id查询用户的业务");
        UserStandardVO standarById = userRepository.getStandarById(userId);
        if (standarById==null){
            String message="获取用户详情失败,尝试访问的用户数据不存在";
            throw new ServiceException(ServiceCode.ERROR_NOT_FOUND,message);
        }
        return standarById;
    }

    @Override
    public PageData<UserListItemVO> list(Integer pageNum, Integer pageSize) {
        log.debug("开始处理查询用户列表");
        return userRepository.list(pageNum,pageSize);
    }

    @Override
    public UserStandardVO getStandarById(Long userId) {
        log.debug("开始处理根据Id查询用户信息");
        return userRepository.getStandarById(userId);
    }

    /**
     * 修改用户的启用状态
     *
     * @param id     用户ID
     * @param enable 新的启用状态
     * @see cn.tedu.tmall.common.consts.data.CommonConsts#ENABLE_STATE_ON
     * @see cn.tedu.tmall.common.consts.data.CommonConsts#ENABLE_STATE_OFF
     */
    private void updateEnableById(Long id,Integer enable){
        log.debug("开始处理用户的启用禁用状态");
        if (id==1){
            String message="用户不存在,访问数据失败";
            throw new ServiceException(ServiceCode.ERROR_NOT_FOUND,message);
        }

        // 根据用户id查询,用户是否存在
        UserStandardVO queryResult = userRepository.getStandarById(id);
        if (queryResult==null){
            String message="用户不存在,访问数据不存在";
            throw new ServiceException(ServiceCode.ERROR_NOT_FOUND,message);
        }

        // 判断用户当前状态是否与要修改的状态一样,如果一样,就不需要修改状态
        if(queryResult.getEnable().equals(enable)){
            String message= ENABLE_STATE_TEXT[enable] + "用户失败，当前用户已经处于"
                    + ENABLE_STATE_TEXT[enable] + "状态！";
            throw new ServiceException(ServiceCode.ERROR_CONFLICT,message);
        }

        User user=new User();
        user.setId(id);
        user.setEnable(enable);
        int i = userRepository.updateById(user);
        if(i!=1){
            String message = ENABLE_STATE_TEXT[enable] + "用户失败，服务器忙，请稍后再次尝试！";
            throw new ServiceException(ServiceCode.ERROR_UPDATE,message);
        }

        // 将用户的状态存到缓存中
        if (enable.equals(ENABLE_STATE_OFF)){
            UserStatePO userState = userCacheRepository.getUserState(id);
            // 如果用户存在,将用户的id设置为禁用状态
            if (userState!=null){
                userCacheRepository.setUserDisabled(id);
            }
        }
    }

}
